<?php
/**
 * 操作数据前行为验证
 * 2019.8.3
 */
namespace app\manage\behavior;


use think\Validate;
use app\common\model\TokenCheck;
use think\Db;
use think\Model;
use think\Request;

class Check
{
	public function appBegin(&$params)
	{
		$input = input();
        $excludeSign = [
            'share/ping_address/pingAddress',//ping不验证签名
            'share/ip_store/upExcel',//文件上传不验证sign
            'manage/staff/createStaff',
            'share/ping_ip/pingIcMp',
            'share/ping_ip/pingAddress',
            'share/ping_ip/pingMonth',
            'share/ping_ip/pingDay',
            'share/ping_ip/pingTest',
        ];
        //验证签名
        if( !in_array($action = $this->getAction($params), $excludeSign) )
        {
            $this->checkSign($input); //验证签名
        }
        //不需要登陆的模块/控制器/方法
        $exclude = [
            'manage/admin_login/adminLogin',
            'manage/admin_login/setFirstPassword',
            'share/ping_address/pingAddress',
            'share/ping_ip/pingAllIp',
            'share/ping_address/ping',
            'share/ip_store/retrievePwd',
            'share/ip_store/retrievePwdAdd',
            'share/ping_ip/historyDownLoad',//下载测试
            'share/ping_ip/pingIcMp',
            'share/ping_ip/pingAddress',
            'share/ping_ip/pingMonth',
            'share/ping_ip/pingDay',
            'share/ping_ip/pingTest',
        ];

        if( !in_array($action = $this->getAction($params), $exclude) ){
           //没有在$exclude数组里面的都需要验证登陆,token是否存在
           $validate = new Validate([
               ['token', 'require', 'token不能为空'],
           ]);
           if(!$validate->check($input))
           {
               returnJson(-1001,  $validate->getError())->send();die;
           }
           $TokenCheck = new TokenCheck();
           $TokenCheck->checkToken( $input['token'] );
        }
	}



    //解析操作形成
    private function getAction($params){
        if(isset($params['module'])){
            return $params['module'][0]."/".$params['module'][1]."/".$params['module'][2];
        }else{
            return "";
        }
    }

	//验证签名,确保接口数据安全和避免重放
	private function checkSign( $input ){
        $sign      = trim(Request::instance()->header('sign'));
        $timestamp = trim(Request::instance()->header('timestamp'));
        if(!$sign)
        {
            echo json_encode(["code" => -9006,'msg'=>"sign参数异常"]);die;
        }
        if(!$timestamp)
        {
            echo json_encode(["code" => -9007,'msg'=>"timestamp参数异常"]);die;
        }
        //请求仅在30s有效
        if( abs($timestamp - time()) >=30 )
        {
//            returnJson(-9008,  "当前url请求超时")->send();die;
        }
        $from_sign = $sign;
        $input['timestamp'] = $timestamp;
        $sign = $this->getSign( $input );
        if( $from_sign !== $sign ){
        	returnJson(-9009,  "签名验证失败")->send();die;
        }
	}

	/*
     *  生成sign签名  yuYan123456!@#
     */
    private function getSign( $data )
    {
        foreach ($data as $k => $v) {
            if(null === $v && $v !== 0 ){
                unset($data[$k]);
            }
        }
        foreach ($data as $k => $v)
        {
            $Parameters[strtolower($k)] = $v;
        }
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, TRUE);
        $String = $String."&key=".config('api_sign_key');
        $result_ = strtoupper( md5( $String ) );
        return $result_;
    }

    //将数组转成uri字符串
    private function formatBizQueryParaMap($paraMap, $urLenCode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v)
        {
            if($urLenCode)
            {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar = "";
        if (strlen($buff) > 0)
        {
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }



}